#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Sequence ':all';

sub factors { my $n=shift; my $f=[2]; do { $n%$_ || push(@$f,$_) } for 2..$n-1; [@$f,$n] }
my $primes_1 = Concat [2], Filter { @{ factors($_) }==2 } Range[3,5..INF];

sub factorial { my $n=shift; my $p=1; $p*=$_ for 2..$n; $p }
my $primes_2 = Concat [2], Filter { $_!=2 } Map { 2+(2*factorial($_))%($_+1) } Range[0..INF];

sub is_prime { my $n=shift()-1; return 1 if $n==1; return unless (2*factorial($n))%($n+1); 1 }
my $primes_3 = Filter { is_prime $_ } Range[1..INF];

say show take 30 => $_ for Primes, $primes_1, $primes_2, $primes_3;

my $Wallis = ( (Range[2,4..INF])/(Range[1,3..INF]) ) * ( (Range[2,4..INF])/(Range[3,5..INF]) );
say 2 * Product Range[ $Wallis, 0..2000 ];

my $Leibniz = (-1)**(Range[0..INF]) / Range[1,3..INF];
say 4 * Sum Range[ $Leibniz, 0..1000 ];

my $reciprocal_factorials = Map { 1/factorial($_) } Range[0..INF];
say Sum Range[ $reciprocal_factorials, 0..100 ];
